<template>
  <transition name="modal-fade">
    <!-- Modal Overlay -->
    <div v-if="visible" class="modal-overlay" @click="handleOverlayClick">
      <!-- Modal Content Box -->
      <div class="modal-box" :style="modalStyle" @click.stop>
        <!-- Optional Header -->
        <div v-if="showTitleBar" class="modal-header">
          <slot name="header">
            <span class="modal-title">{{ title }}</span>
          </slot>
          <button
            v-if="showClose"
            type="button"
            class="modal-close-btn"
            @click="closeModal"
            aria-label="Close"
          >
            &times;
          </button>
        </div>

        <!-- Main Content Body (Scrollable) -->
        <div class="modal-body">
          <!-- Default slot for the main content -->
          <slot></slot>
        </div>
        <!-- Download Button added inside modal-box -->
        <div class="download-button" v-if="down" @click="downloadF()">
          <img src="../../assets/images/down.png" alt="" class="downImg" />
          下载
        </div>
      </div>
      <!-- Footer Area -->
      <div v-if="$slots.footer" @click.stop class="modal-footer">
        <!-- Named slot for the footer content -->
        <slot name="footer"></slot>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  name: "CustomModal",
  props: {
    // Control visibility (use .sync or v-model in parent)
    visible: {
      type: Boolean,
      required: true,
    },
    down: {
      type: Boolean,
      default: false,
    },
    downUrl: {
      type: String,
      default: "",
    },
    title: {
      type: String,
      default: "提示",
    },
    width: {
      type: String,
      default: "60%", // Adjust default width as needed
    },
    maxWidth: {
      type: String,
      default: "800px", // Max width for larger screens
    },
    // Allow closing by clicking the overlay
    closeOnClickOverlay: {
      type: Boolean,
      default: true,
    },
    // Show the default header bar
    showTitleBar: {
      type: Boolean,
      default: true,
    },
    // Show the default close button in the header
    showClose: {
      type: Boolean,
      default: true,
    },
    // Prevent background scroll when modal is open
    preventScroll: {
      type: Boolean,
      default: true,
    },
    customClass: {
      type: String,
      default: "",
    },
    customStyle: {
      type: Object,
      default: () => ({}),
    },
  },
  computed: {
    modalStyle() {
      return {
        width: this.width,
        maxWidth: this.maxWidth,
        ...this.customStyle,
      };
    },
  },
  watch: {
    visible(newVal) {
      if (this.preventScroll) {
        if (newVal) {
          // Prevent body scroll
          document.body.style.overflow = "hidden";
          this.$emit("open"); // Emit open event
        } else {
          // Restore body scroll
          // Check if other modals might still be open before restoring
          // For simplicity, we'll just restore it here.
          document.body.style.overflow = "";
          this.$emit("close"); // Emit close event
        }
      } else {
        if (newVal) this.$emit("open");
        else this.$emit("close");
      }
    },
  },
  methods: {
    async downloadF() {
      console.log("Attempting download for:", this.downUrl);
      if (!this.downUrl) {
        console.error("Download URL is missing.");
        this.$message.error("下载地址无效！"); // Notify user
        return;
      }

      // Add a loading indicator if desired
      // this.loading = true;

      try {
        // 1. Fetch the file data
        const response = await fetch(this.downUrl);

        if (!response.ok) {
          // Handle HTTP errors (e.g., 404 Not Found, 403 Forbidden)
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        // 2. Get the data as a Blob
        const blob = await response.blob();

        // 3. Create an Object URL for the Blob
        const objectUrl = URL.createObjectURL(blob);

        // 4. Create a temporary link element
        const link = document.createElement("a");
        link.href = objectUrl;

        // 5. Set the download attribute (try to get filename from URL or headers)
        let filename = "download"; // Default filename
        // Try getting filename from Content-Disposition header first (if available via CORS)
        const disposition = response.headers.get("content-disposition");
        if (disposition && disposition.indexOf("attachment") !== -1) {
          const filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
          const matches = filenameRegex.exec(disposition);
          if (matches != null && matches[1]) {
            filename = matches[1].replace(/['"]/g, "");
          }
        } else {
          // Fallback: try extracting filename from the URL path
          try {
            const urlPath = new URL(this.downUrl).pathname;
            const lastSegment = urlPath.substring(urlPath.lastIndexOf("/") + 1);
            if (lastSegment) filename = decodeURIComponent(lastSegment);
          } catch (e) {
            console.warn("Could not parse filename from URL", e);
          }
        }
        link.setAttribute("download", filename);

        // 6. Programmatically click the link to trigger download
        document.body.appendChild(link); // Required for Firefox
        link.click();

        // 7. Clean up: remove the link and revoke the Object URL
        document.body.removeChild(link);
        URL.revokeObjectURL(objectUrl);

        console.log("Download initiated for:", filename);
      } catch (error) {
        console.error("Download failed:", error);
        this.$message.error(`下载失败: ${error.message}`); // Notify user
      } finally {
        // Remove loading indicator if you added one
        // this.loading = false;
      }
    },
    closeModal() {
      this.$emit("update:visible", false);
    },
    handleOverlayClick() {
      if (this.closeOnClickOverlay) {
        this.closeModal();
      }
    },
  },
  beforeDestroy() {
    // Ensure body scroll is restored if component is destroyed while visible
    if (this.preventScroll && this.visible) {
      document.body.style.overflow = "";
    }
  },
};
</script>

<style scoped>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.6);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  /* Ensure overlay is on top */
  transition: opacity 0.3s ease;
}

.modal-box {
  background-color: #fff;
  border-radius: 6px;
  /* box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); */
  display: flex;
  flex-direction: column;
  /* overflow: hidden; /* Important: Let modal-body handle scroll */
  max-height: 80vh;
  /* Limit max height */
  min-height: 75vh;
  position: relative;
  /* Added for absolute positioning of children */
  z-index: 1001;
  transition: transform 0.3s ease, opacity 0.3s ease;
  /* Default width/maxWidth applied via :style */
  /* Add overflow: visible if the button gets clipped */
  /* overflow: visible; */
}

.modal-header {
  padding: 15px 20px;
  border-bottom: 1px solid #e9ecef;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-shrink: 0;
  /* Prevent header from shrinking */
}

.modal-title {
  font-size: 1.1rem;
  font-weight: 600;
  margin: 0;
}

.modal-close-btn {
  background: none;
  border: none;
  font-size: 1.8rem;
  line-height: 1;
  color: #6c757d;
  cursor: pointer;
  padding: 0;
  opacity: 0.7;
}

.modal-close-btn:hover {
  opacity: 1;
  color: #000;
}

.modal-body {
  /* padding: 20px; */
  /* Padding is applied in the user's content div */
  overflow-y: auto;
  /* Make body scrollable if content exceeds max-height */
  flex-grow: 1;
  /* Allow body to take available space */
  /* Background color is applied in user's content div */
  padding: 15px;
}

/* Style for the download button */
.download-button {
  position: absolute;
  bottom: 40px;
  /* Align bottom edge with modal-box bottom */
  right: -80px;
  /* Align right edge with modal-box right */
  transform: translate(0, calc(100% + 5px));
  /* Move it down below the box + 5px gap */
  width: auto;
  padding: 5px 15px;
  height: 30px;
  background-color: #1c1d22;
  color: #fff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  z-index: 1002;
  /* Ensure it's visible */
  display: flex;
  align-items: center;
  justify-content: center;
}

.downImg {
  width: 15px;
  margin-right: 5px;
}

.modal-footer {
  width: 100%;
  flex: 1;
  /* Prevent footer from shrinking */
  background-color: #f2f2f2;
  padding-top: 10px;
}

/* --- Transition Styles --- */
.modal-fade-enter-active,
.modal-fade-leave-active {
  transition: opacity 0.3s ease;
}

.modal-fade-enter-active .modal-box,
.modal-fade-leave-active .modal-box {
  transition: all 0.3s ease;
  /* Animate transform and opacity */
}

.modal-fade-enter,
.modal-fade-leave-to {
  opacity: 0;
}

.modal-fade-enter .modal-box,
.modal-fade-leave-to .modal-box {
  opacity: 0;
  transform: translateY(-20px) scale(0.95);
}

/* --- Styles for user's content (optional, put in parent or global CSS) --- */
/* These are just placeholders based on your provided footer snippet */
.footer {
  /* Class from your snippet */
  background-color: #f2f2f2;
  padding: 10px 0;
  width: 100%;
  text-align: center;
  font-size: 13px;
  /* Example size */
  color: #555;
  /* Example color */
}

.footer .tips {
  margin-top: 10px;
  margin-bottom: 15px;
  font-size: 14px;
  color: #333;
}

.footer .underline {
  text-decoration: underline;
  font-weight: bold;
  color: #e6a23c;
  /* Example color */
  margin: 0 3px;
}

.footer .el-button + .el-button {
  margin-left: 10px;
}
</style>
